package com.digital.smartgrow.service.expert.impl;
import java.time.LocalDateTime;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.digital.smartgrow.common.util.BeanCopyUtil;
import com.digital.smartgrow.dao.expert.ExpertPlanMapper;
import com.digital.smartgrow.dto.expert.ExpertAttendDTO;
import com.digital.smartgrow.dto.expert.ExpertPlanPageDTO;
import com.digital.smartgrow.entity.business.UpJob;
import com.digital.smartgrow.entity.business.UpJobLog;
import com.digital.smartgrow.entity.datacenter.Teacher;
import com.digital.smartgrow.entity.expert.Expert;
import com.digital.smartgrow.entity.expert.ExpertChoose;
import com.digital.smartgrow.entity.expert.ExpertGroup;
import com.digital.smartgrow.entity.expert.ExpertPlan;
import com.digital.smartgrow.entity.export.ExportApprove;
import com.digital.smartgrow.service.business.UpJobLogService;
import com.digital.smartgrow.service.business.UpJobService;
import com.digital.smartgrow.service.datacenter.TeacherService;
import com.digital.smartgrow.service.expert.ExpertChooseService;
import com.digital.smartgrow.service.expert.ExpertGroupService;
import com.digital.smartgrow.service.expert.ExpertPlanService;
import com.digital.smartgrow.service.expert.ExpertService;
import com.digital.smartgrow.service.expert.random.RandomExpertGenerate;
import com.digital.smartgrow.service.export.ExportApproveService;
import com.digital.smartgrow.vo.expert.ExpertGroupVo;
import com.digital.smartgrow.vo.expert.ExpertPlanVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 专家方案 服务实现类
 * </p>
 *
 * @author sunyuechao
 * @since 2022-07-18
 */
@Service
public class ExpertPlanServiceImpl extends ServiceImpl<ExpertPlanMapper, ExpertPlan> implements ExpertPlanService {
@Autowired
private ExpertGroupService groupService;
@Autowired
private UpJobService upJobService;

@Autowired
private ExportApproveService exportApproveService;

@Autowired
private ExpertChooseService expertChooseService;

    @Autowired
    private  ExpertService expertService;
    @Autowired
    private RandomExpertGenerate generate;
@Autowired
private ExpertPlanService expertPlanService;
@Autowired
private UpJobLogService upJobLogService;
@Autowired
private TeacherService teacherService;
@Autowired
private ExpertGroupService expertGroupService;

    @Override
    public Object getListByPage(ExpertPlanPageDTO pageDTO) {
        Page<ExpertPlan> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        QueryWrapper<ExpertPlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(pageDTO.getYear()), "year", pageDTO.getYear());
        queryWrapper.like(StringUtils.isNotBlank(pageDTO.getName()), "name", pageDTO.getName());
        Page<ExpertPlan> expertPlanPage = this.page(page, queryWrapper);
        return expertPlanPage;

    }

    @Override
    public ExpertPlanVo getInfo(Integer id) {
        ExpertPlan expertPlan = this.getById(id);
        ExpertPlanVo expertPlanVo= BeanCopyUtil.copyProperties(expertPlan, ExpertPlanVo::new);
        //获取系列
        if(expertPlan.getUpJobId()!=null){
            UpJob upJob = upJobService.getInfo(expertPlan.getUpJobId());
            BeanCopyUtil.copyNotEmptyProperties(upJob, expertPlanVo);
            //BeanUtil.copyProperties(upJob,expertPlanVo);
        }

        List<ExpertGroup> list = groupService.lambdaQuery().in(ExpertGroup::getPlanId, id).list();

        List<ExpertGroupVo> groupVos = BeanCopyUtil.copyListProperties(list, ExpertGroupVo::new);
        //是否抽选完毕,回显已抽选专家列表
        if(expertPlan.getStatus()!=0){
            for(int i=0;i<groupVos.size();i++){
                setExpertLists( groupVos.get(i));
            }
        }
        expertPlanVo.setExpertGroupList(groupVos);
        return expertPlanVo;
    }

    /**
     * 获取抽选专家列表及核定状态
     * @param vo
     * @return
     */
    private void setExpertLists(ExpertGroupVo vo){
        List<Expert> list=new ArrayList<>();
        List<ExpertChoose> list1 = expertChooseService.lambdaQuery().eq(ExpertChoose::getPlanId, vo.getPlanId())
                .eq(ExpertChoose::getGroupId, vo.getId()).list();
        for (ExpertChoose e:
                list1) {
            list.add(expertService.getById(e.getExpertId()));
        }
        vo.setExpertLists(list);
    }

    @Override
    public Object saveAll(ExpertPlanVo expertPlanVo) {
        ExpertPlan expertPlan = BeanCopyUtil.copyProperties(expertPlanVo, ExpertPlan::new);
        this.save(expertPlan);
        List<ExpertGroupVo> expertGroupList = expertPlanVo.getExpertGroupList();
        if(expertGroupList.size()>0){
            Integer id = expertPlan.getId();
            List<ExpertGroup> expertGroups = BeanCopyUtil.copyListProperties(expertGroupList, ExpertGroup::new,
                    (vo,dto)->{
                       dto.setPlanId(id);
                        dto.setPlanId(id);
                    }
                    );
            groupService.saveBatch(expertGroups);
        }
        return null;
    }

    @Override
    public Object updateAll(ExpertPlanVo expertPlanVo) {

        //先移除在添加
        if(removeItemByLinkId(expertPlanVo.getId())){
            List<ExpertGroupVo> expertGroupList = expertPlanVo.getExpertGroupList();
            if(expertGroupList.size()>0){
                Integer id = expertPlanVo.getId();
                List<ExpertGroup> expertGroups = BeanCopyUtil.copyListProperties(expertGroupList, ExpertGroup::new,
                        (vo,dto)->{
                            dto.setPlanId(id);
                            dto.setPlanId(id);
                        }
                );
                groupService.saveBatch(expertGroups);
            }
        }

        ExpertPlan expertPlan = BeanCopyUtil.copyProperties(expertPlanVo, ExpertPlan::new);
        return this.updateById(expertPlan);
    }

    @Override
    public Object removeAll(Integer id) {
        if(removeItemByLinkId(id)){
            return this.removeById(id);
        }
        return false;
    }

    /**
     * 开始抽选
     *
     * @param id
     * @return
     */
    @Override
    public List<ExpertGroupVo> chooseStart(Integer id) {
        //TODO:先删除原来的抽选结果
        ExpertPlan byId = this.getById(id);
        byId.setStatus(0);
        this.updateById(byId);
        List<ExpertChoose> removes = expertChooseService.lambdaQuery().eq(ExpertChoose::getPlanId, id).list();
        for(ExpertChoose c:removes){
            expertChooseService.removeById(c);
        }
        ExpertPlanVo info = this.getInfo(id);
        List<ExpertGroupVo> expertGroupList = info.getExpertGroupList();
        for(int i=0;i<expertGroupList.size();i++){
            //todo:应该考虑权重，如果有数量限制

            //@ApiModelProperty(value = "学科")
            //    private String archives;
            //
            //    @ApiModelProperty(value = "专业")
            //    private String major;
            List<Expert> list = expertService.lambdaQuery()
                    .eq(Expert::getStatus,1)
                    .eq(StringUtils.isNotBlank(expertGroupList.get(i).getArchives()),Expert::getSeries, expertGroupList.get(i).getArchives())
                    .eq(StringUtils.isNotBlank(expertGroupList.get(i).getMajor()),Expert::getMajor, expertGroupList.get(i).getMajor()).list();
            expertGroupList.get(i).setExpertLists(list);

        }
        return expertGroupList;

    }

    /**
     * 停止抽选
     *
     * @param expertChoose
     * @return
     */
    @Override
    public List<ExpertGroupVo> chooseEnd(List<ExpertGroupVo> expertChoose) {
        for(int i=0;i<expertChoose.size();i++){
            List<Expert> expertLists = expertChoose.get(i).getExpertLists();
            // ExpertPlan expertPlan = BeanCopyUtil.copyProperties(expertPlanVo, ExpertPlan::new);
            List<Expert> experts = null;

            try {
                experts = generate.generateAll(expertLists, expertChoose.get(i).getParkCount());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            expertChoose.get(i).setExpertLists(experts);
        }
        return expertChoose;
    }

    /**
     * 保存抽选
     *
     * @param expertChoose
     * @return
     */
    @Override
    public Object chooseSave(List<ExpertGroupVo> expertChoose) {
        Integer planId = expertChoose.get(0).getPlanId();
        for(int i=0;i<expertChoose.size();i++){
            List<Expert> list = expertChoose.get(i).getExpertLists();
            for(int j=0;j<list.size();j++){
                ExpertChoose e=new ExpertChoose();
                e.setExpertId(list.get(j).getId());
                e.setPlanId(planId);
                e.setGroupId(expertChoose.get(i).getId());
                e.setStatus(0);
                e.setStatusRemark("");
                e.setPartake(0);
                e.setLastTime(LocalDateTime.now());
                e.setCreateTime(LocalDateTime.now());
                e.setUpdateTime(LocalDateTime.now());
                expertChooseService.save(e);
            }
        }
        ExpertPlan byId = this.getById(planId);
        byId.setStatus(1);
        this.updateById(byId);
        return "保存完毕";
    }

    @Override
    public Object attend(ExpertAttendDTO expertAttendDTO) {
        //删除数据
        List<ExportApprove> list = exportApproveService.lambdaQuery()
                .eq(ExportApprove::getExportId, expertAttendDTO.getExpertId())
                .eq(ExportApprove::getExportPlanId, expertAttendDTO.getPlanId())
                .eq(ExportApprove::getExpertGroupId, expertAttendDTO.getGroupId())
                .list();
        if(list!=null){
            for(ExportApprove e:list){
                exportApproveService.removeById(e);
            }
        }
        //如果出席，生成核定数据表--修改到专家登录处 TODO
        if(expertAttendDTO.getStatus()==1){
            ExpertPlan expertPlan = expertPlanService.getById(expertAttendDTO.getPlanId());
            ExpertGroup expertGroup = expertGroupService.getById(expertAttendDTO.getGroupId());
            //ExpertChoose expertChoose = expertChooseService.getById(expertAttendDTO.getGroupId());
            UpJob upJob = upJobService.getById(expertPlan.getUpJobId());
            Expert expert = expertService.getById(expertAttendDTO.getExpertId());

            List<UpJobLog> upJobLogs = upJobLogService.lambdaQuery().
                       eq(UpJobLog::getUpJobCode,upJob.getId()).list();
            for(UpJobLog l:upJobLogs){
                Teacher teacher = teacherService.getInfoByUserName(l.getUserCode());
                //审核状态 待审核：0，审核中：1，通过：2，打回重新申报：-1,不通过：-2"
                String res="";
                switch (upJob.getStatus()){
                    case 0: res="待审核";break;
                    case 1: res="审核中";break;
                    case 2: res="通过";break;
                    case -1: res="打回重新申报";break;
                    case -2: res="不通过";break;
                }
                String remarks=expert.getName()+"-审核:"+teacher.getName()+"->申报的【"+upJob.getName()+"】职评项，";
                remarks=remarks+"当前流程审核状态为：【"+res+"】，";
                remarks=remarks+"所在审批方案为：【"+expertPlan.getName()+"】，";
                remarks=remarks+"审批组为：【"+expertGroup.getName()+"】";
                //-------
                ExportApprove exportApprove=new ExportApprove();
                exportApprove.setExportId(expertAttendDTO.getExpertId());//
                exportApprove.setUserCode(l.getUserCode());

                exportApprove.setUpBaseId(l.getUpBaseId());
                exportApprove.setExpertGroupId(expertAttendDTO.getGroupId());//
                exportApprove.setUpJobId(l.getUpJobCode());
                exportApprove.setUpJobLogId(l.getId());
                exportApprove.setExportPlanId(expertAttendDTO.getPlanId());//
                exportApprove.setRemarks(remarks);
                exportApprove.setIsProcess(upJob.getStatus());
                exportApprove.setIsApprive(0);
                exportApprove.setAppriveTime(null);
                exportApprove.setCreateTime(LocalDateTime.now());
                exportApproveService.save(exportApprove);
            }
        }


        //修改核定状态
        ExpertChoose one = expertChooseService.lambdaQuery()
                .eq(ExpertChoose::getExpertId, expertAttendDTO.getExpertId())
                .eq(ExpertChoose::getPlanId, expertAttendDTO.getPlanId())
                .eq(ExpertChoose::getGroupId, expertAttendDTO.getGroupId()).one();
        if(one==null){
            return "参数传递错误";
        }
        one.setStatus(expertAttendDTO.getStatus());
        one.setStatusRemark(expertAttendDTO.getStatusRemark());
        expertChooseService.updateById(one);
        //判断是否全部核定，对方案修改状态
        List<ExpertChoose> list2 = expertChooseService.lambdaQuery()
                .eq(ExpertChoose::getPlanId, expertAttendDTO.getPlanId())
                .eq(ExpertChoose::getStatus, 0).list();
        //没有核定完毕按钮
        if(list2.size()<=0||list2==null){//todo:有点问题
            ExpertPlan byId = this.getById(expertAttendDTO.getPlanId());
            byId.setStatus(1);//状态（0：待抽选，1：已抽选/待核定，2：已核定
            this.updateById(byId);
            return "全部专家核定完毕";
        }
        return "单独专家核定完毕";
    }

    //移除方案子项
    private boolean removeItemByLinkId(Integer linkId) {
        List<ExpertGroup> list = groupService.lambdaQuery().in(ExpertGroup::getPlanId, linkId).list();
        for(ExpertGroup g:list){
            groupService.removeById(g);
        }
        //return groupService.removeByIds(list);
        return true;

    }

    //公共变量 赛选
//    private  List<Expert> waitExpert=new ArrayList<>();
//    private   List<Expert> chooseExpert=new ArrayList<>();
}
